home *** CD-ROM | disk | FTP | other *** search
/ Speccy ClassiX 1998 / Speccy ClassiX 98.iso / amiga_system / the_aminet / dev / gcc / ixemulsrc.lha / ixemul-41.4 / gen_library / getwd.c < prev    next >
C/C++ Source or Header  |  1995-05-28  |  5KB  |  205 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Ray Burr
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. /* Written and Copyright by Ray Burr. 
  21.  * Put under the GNU Library General Public License.
  22.  * Thanks Ray !
  23.  */
  24.  
  25. #define KERNEL
  26. #include "ixemul.h"
  27. #include "kprintf.h"
  28.  
  29. #ifndef MAXPATHLEN
  30. #define MAXPATHLEN 1024
  31. #endif
  32.  
  33. /* _GetPathFromLock - Given a pointer to an AmigaDOS Lock structure, build
  34.    a rooted path string in a buffer of a given size.  The buffer should be
  35.    at least 'buffer_length' bytes.  Returns a pointer to the result
  36.    or NULL on an error.  'errno' will be set in the case of an error.  This
  37.    function returns the path string based at 'buffer[0]' but it can alter
  38.    any part of the buffer.  */
  39.  
  40. static char *
  41. _GetPathFromLock (BPTR lock, char *buffer, int buffer_length)
  42. {
  43.   char *p;
  44.   BPTR fl, next_fl;
  45.   int length;
  46.   struct FileInfoBlock *fib;
  47.   int omask;
  48.   char *result = 0;
  49.  
  50.   /* Allocate space on stack for fib. */
  51.  
  52.   BYTE fib_Block[sizeof (struct FileInfoBlock) + 2];
  53.  
  54.   /* Make sure fib is longword aligned. */
  55.  
  56.   fib = (struct FileInfoBlock *) fib_Block;
  57.   if (((ULONG) fib & 0x02) != 0)
  58.     fib = (struct FileInfoBlock *) ((ULONG) fib + 2);
  59.  
  60.   p = 0L;
  61.  
  62.   /* Duplicate the lock so that the directory structure can't change
  63.      while we're doing this. */
  64.  
  65.   omask = syscall (SYS_sigsetmask, ~0);
  66.   fl = DupLock (lock);
  67.  
  68.   /* Follow the chain of directories and build the name in 'buffer' */
  69.  
  70.   while (fl != 0L)
  71.     {
  72.       if (Examine (fl, fib) == DOSFALSE)
  73.     {
  74.       errno = __ioerr_to_errno(IoErr());
  75.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  76.       UnLock (fl);
  77.       goto ret;
  78.     }
  79.       next_fl = ParentDir (fl);
  80.       UnLock (fl);
  81.       if (p != 0L)
  82.     {
  83.       if (next_fl != 0L)
  84.         *--p = '/';
  85.       else
  86.         *--p = ':';
  87.     }
  88.       else
  89.     {
  90.       p = buffer + buffer_length - 1;    /* fix 20-jan-92 ## mw */
  91.       *p = '\0';
  92.       if (next_fl == 0L)
  93.         *--p = ':';
  94.     }
  95.       length = strlen (fib->fib_FileName);
  96.       p -= length;
  97.       if (p <= buffer)
  98.     {
  99.       if (next_fl != 0L)
  100.         UnLock (next_fl);
  101.       goto ret;
  102.     }
  103.       bcopy (fib->fib_FileName, p, length);
  104.       fl = next_fl;
  105.     }
  106.  
  107.   /* Move the pathname so that it starts at buffer[0]. */
  108.  
  109.   bcopy (p, buffer, strlen (p) + 1);
  110.  
  111.   result = buffer;
  112.  
  113. ret:
  114.   syscall (SYS_sigsetmask, omask);
  115.   return result;
  116. }
  117.  
  118.  
  119. static char *
  120. _get_pwd (char *buffer, int buffer_length)
  121. {
  122.   struct Process *proc;
  123.   char *result, *colon;
  124.   extern char *index (const char *, int);
  125.  
  126.   proc = (struct Process *) FindTask (0L);
  127.  
  128.   /* Just return an empty string if this is not a process. */
  129.  
  130.   if (proc == 0L || proc->pr_Task.tc_Node.ln_Type != NT_PROCESS)
  131.     {
  132.       buffer[0] = '\0';
  133.       return buffer;
  134.     }
  135.  
  136.   /* make room for slash */
  137.   if (ix.ix_translate_slash)
  138.     buffer++;
  139.  
  140.   if (GetCurrentDirName (buffer, buffer_length) ||
  141.       NameFromLock (proc->pr_CurrentDir, buffer, buffer_length))
  142.     {
  143.       errno = 0;
  144.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  145.       result = buffer;
  146.       goto returnit;
  147.     }
  148.   /* and as the last chance resort to the 1.3 algorithm */
  149.  
  150.   result = _GetPathFromLock (proc->pr_CurrentDir, buffer, buffer_length);
  151.  
  152. returnit:
  153.   if (ix.ix_translate_slash && result)
  154.     {
  155.       if (colon = index (result, ':'))
  156.         {
  157.       *colon = '/';
  158.           result--;
  159.           result[0] = '/';
  160.       return result;
  161.         }
  162.  
  163.        bcopy (result, result - 1, strlen (result) + 1);
  164.        return result - 1;
  165.     }
  166.  
  167.   return result;
  168. }
  169.  
  170.  
  171. char *
  172. getwd (char *buffer)
  173. {
  174.   char *path;
  175.  
  176.   path = _get_pwd (buffer, MAXPATHLEN);
  177.   if (path == 0L)
  178.     {
  179.       strcpy (buffer, "getwd - ");
  180.       strcat (buffer, strerror (errno));
  181.       return 0L;
  182.     }
  183.  
  184.   return path;
  185. }
  186.  
  187.  
  188. char *
  189. getcwd (char *buffer, int buffer_length)
  190. {
  191.  
  192.   if (buffer == 0L)
  193.     {
  194.       buffer = (char *) syscall (SYS_malloc, buffer_length + 2);
  195.       if (buffer == 0L)
  196.     {
  197.       errno = ENOMEM;
  198.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  199.       return 0L;
  200.     }
  201.     }
  202.  
  203.   return _get_pwd (buffer, buffer_length);
  204. }
  205.